// board class - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Board class
chess_spider.Board = function( move ) {

	// params
	this.root_mv = move;
	this.cur_mv = move;
	this.game_arr = [];
	if( move ) this.game_arr[move.game.idx] = { 'root': move, 'cur': move };

	// assign this for closure functions
	var bd = this;

	// attributes
	this.dom_div = document.createElement('div');

	// for unique naming
	this.seq = chess_spider.util.nextSeq();

	// hilite and border colors
	this.color_idx = chess_spider.Board.nextColorIdx();

	// create document board
	this.dom_div = E.div( '.cs__board_container',
			E.div( '.cs__promotion_notify', 'Click on Promoted Piece to change' ),
			E.a( 'board', null, ':cs__B'+bd.seq+'-table',
				E.table( '.cs__board', {'s.borderColor':bd.hilitBorderColor()} ) ),
			E.div( '.cs__promotion_notify', 'Click on Promoted Piece to change' ),
			E.div( '.cs__panel', {'s.borderColor':bd.hilitBorderColor()},
				E.div( '.cs__panel_move',
					E.a( 'toggle', toggle, ':cs__B'+bd.seq+'-toggle', 's.paddingRight:2px', '\u2297' ),
					E.button( jump, '`...' ),
					E.button( jump, '\u003c\u003c' ),
					E.button( jump, '\u003c' ),
					E.button( jump, '\u003e' ),
					E.button( jump, '\u003e\u003e' ),
					E.button( jump, '`....' ),
					E.button( backspace, '\u226e', {'disabled':'disabled'} ),
					E.span( '.cs__last_move', 's.fontSize:14px', '- -' ),
					E.a( 'toggle', commentToggle, ':cs__B'+bd.seq+'-toggle', '\u2295' ) ),
				E.form( '.cs__panel_options', 's.display:none', {'e.submit':nullEvent }, 
					E.div( '.cs__panel_header', 's.textAlign:left', 'Annotate This Move:' ),
					E.div( '.cs__panel_precomment', 'a.mode:user', E.input( {'e.blur':comment, 'placeholder':'pre-comment'} ) ),
					E.div( '.cs__panel_nar', 'a.mode:user',
						{ 'iterator': { 'from':1, 'thru':6, 'function':function(i) {
							return( [ E.radio( '.cs__radio', {'value':i, 'name':'nar', 'e.click':nar}), 
							{'text':chess_spider.regx.nar_arr[i]+' '} ] ) }}},
						E.radio('.cs__radio',':nar', {'e.click':nar, 'value':'0'} ), 'n/a' ),
					E.div( '.cs__panel_finish', 'a.mode:user',
						{ 'iterator': { 'from':1, 'thru':7, 'function': function(i) {
							return( [ E.radio( '.cs__radio', {'name':'finish', 'e.click':finish}, i ),
							{'text':chess_spider.regx.finish_disp_arr[i]+' '} ] ) } } },
					       E.radio( '.cs__radio', ':finish', {'e.click':finish, 'value':'0'} ), 'n/a' ),
					E.div( '.cs__panel_comment', E.textarea( {'e.blur':comment, 'placeholder':'move comments' } ) )
				)
			) );

	// event functions
	function nar(e) {
		if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;
		console.log( 'nar' );
		bd.cur_mv.nar = bd.dom_form().getRadio( 'nar' );
		bd.writeLastMove();
		console.log( bd.cur_mv.move + ', '+bd.cur_mv.nar + ', ' + bd.cur_mv.finish );
	};
	function finish(e) {
		if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;
		console.log( 'finish' );
		bd.cur_mv.finish = bd.dom_form().getRadio( 'finish' );
		bd.writeLastMove();
		console.log( bd.cur_mv.move + ', '+bd.cur_mv.nar + ', ' + bd.cur_mv.finish );
	};
	function comment(e) {
		if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;
		console.log( 'comment from ' + e.target.tagName );

		// value
		var val = e.target.value.trim();
		if( val.length==0 ) val = null;

		// set to correct comment
		if( e.target.tagName == 'INPUT' )					bd.cur_mv.pre_comment = val;
		else if( bd.cur_mv.game.mode != 'user' && bd.cur_mv.mode == 'user' )	bd.cur_mv.ucomment = val;
		else									bd.cur_mv.comment = val;

		// display comment in movelist
		bd.cur_mv.showComments();
	};
	function jump(e) {
		e.stopPropagation();
		e.preventDefault();
		if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;
		// if no root_mv, forget about it
		bd.userJump( e.target.innerText );
	};
	function backspace(e) {
		e.stopPropagation();
		e.preventDefault();
		if( e.target.disabled ) return;
		if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;
		// if no root_mv, forget about it
		var move = chess_spider.state.cur_bd.cur_mv;
		if( move.mode == 'user' ) move.userDelete( false );
	};
	function toggle(e) {
		e.stopPropagation();
		e.preventDefault();
		if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;
		bd.dom_table().displayToggle();
		if( bd.fixedboard() ) bd.fixedboard().reposition( bd.dom_table() );
	};
	function commentToggle(e) { 

		e.stopPropagation();
		e.preventDefault();
		if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;
		
		// whether comments currently displayed
		var toDisplay = ((bd.dom_panel_options().style.display == 'none') && bd.cur_mv && bd.cur_mv.level>0);

		// if no display, reset dom_panel_options, and done
		if( !toDisplay )  bd.dom_panel_options().style.display = 'none';

		// otherwise, set according to user attribute
		else {
			bd.dom_panel_options().style.display = 'block';
			var divs = bd.dom_panel_options().querySelectorAll("div [mode='user']");
			for( var i=0; i<divs.length; i++ ) divs[i].style.display = (bd.cur_mv.mode=='user') ? 'block' : 'none';
		}

		// resize
		if( bd.fixedboard() ) bd.fixedboard().reposition( bd.dom_panel_options() );
	};

	// put guts into board
	for( var rank=8; rank>=1; rank=chess_spider.util.decRank(rank) ) {
		var row = document.createElement("TR");
		for( var file='a'; file<='h'; file=chess_spider.util.incFile(file) ) {
			var cell = document.createElement("TD");
			cell.className = ((chess_spider.util.ordFile(file)+rank) % 2) ? 'cs__w' : 'cs__b';
			cell.setAttribute( 'sq', file+rank );
			if( rank==1 || rank==8 ) cell.addEventListener('click',chess_spider.events.cyclePromotion,true);
			cell.addEventListener('dragenter',chess_spider.events.dragenter,true);
			cell.addEventListener('dragover',chess_spider.events.dragover,true);
			cell.addEventListener('dragleave',chess_spider.events.dragleave,true);
			cell.addEventListener('drop',chess_spider.events.drop,true);
			cell.addEventListener('dragend',chess_spider.events.dragend,true);
			row.appendChild( cell );
		}
		this.dom_table().appendChild( row );
	}

	// click to set as current table
	this.dom_table().addEventListener('click',chess_spider.events.boardTouch,true);

	// set move for board
	this.setMove( move );
}

// get all boards instantiated in document
chess_spider.Board.boards = function() {

	var result_arr = new Array();

	// all board containers in document by class
	var dom_arr = document.getElementsByClassName('cs__board_container');
	for( var i=0; i<dom_arr.length; i++ )  result_arr.push( dom_arr[i].cs__getBoard() );

	return result_arr;
}

// attach keystrokes to boards
chess_spider.Board.initAllKeystrokes = function() {
	var boards = chess_spider.Board.boards();
	for( var i=0; i<boards.length; i++ ) boards[i].dom_div.addEventListener('keydown',chess_spider.keyDown,true);
}

// attach board to dom
chess_spider.Board.prototype.attach = function( node ) {

	// make node into a node if an id
	if( typeof node == 'string' ) node = document.getElementById( node );

	// todo: is replace what we want?
	node.parentNode.replaceChild( this.dom_div, node );
}

// Board helpers
chess_spider.Board.prototype.dom_table = function() { return this.dom_div.getElementsByClassName('cs__board')[0]; };
chess_spider.Board.prototype.fixedboard = function() { if(!this.dom_table()) return null; return this.dom_table().cs__getFixedBoard(); };
chess_spider.Board.prototype.dom_promotion = function( color ) { return this.dom_div.getElementsByClassName('cs__promotion_notify')[((color=='w')?0:1)]; };

chess_spider.Board.prototype.dom_panel = function() { return this.dom_div.getElementsByClassName('cs__panel')[0]; };
chess_spider.Board.prototype.dom_form = function() { return this.dom_panel().getElementsByTagName('form')[0]; };
chess_spider.Board.prototype.dom_panel_move = function() { return this.dom_panel().getElementsByTagName('div')[0]; };
chess_spider.Board.prototype.dom_panel_backspace = function() { return this.dom_panel_move().getElementsByTagName('button')[6]; };
chess_spider.Board.prototype.dom_panel_options = function() { return this.dom_panel().getElementsByClassName('cs__panel_options')[0]; };
chess_spider.Board.prototype.dom_pre_comment = function() { return this.dom_panel_options().getElementsByTagName('input')[0]; };
chess_spider.Board.prototype.dom_comment = function() { return this.dom_panel_options().getElementsByTagName('textarea')[0]; };
chess_spider.Board.prototype.dom_last_move = function() { return this.dom_panel().getElementsByClassName('cs__last_move')[0]; };

chess_spider.Board.prototype.square = function( sq ) { return this.dom_div.querySelector( "[sq='"+sq+"']" ); };
chess_spider.Board.prototype.hilitBorderColor = function() { return chess_spider.Board.color_arr[this.color_idx].border; };
chess_spider.Board.prototype.hilitBackgroundColor = function() { return chess_spider.Board.color_arr[this.color_idx].background; };

// set cur - if not arg pass to game
chess_spider.Board.prototype.setCur = function( whether ) {
       	if( whether == undefined ) return (this.root_mv) ? this.root_mv.game.setCur(this) : false;
	this.dom_table().style.boxShadow = ( whether ) ? '5px 5px 5px '+chess_spider.Board.color_arr[this.color_idx].border : '';
	this.dom_panel().style.boxShadow = ( whether ) ? '3px 3px 3px '+chess_spider.Board.color_arr[this.color_idx].border : '';
}

 
// set move for board
chess_spider.Board.prototype.setMove = function( move ) {

	if( !move ) return;

	// set previous state from game
	this.root_mv = move;
	var cur = ( this.game_arr[move.game.idx] && this.game_arr[move.game.idx].root_mv == move ) ? this.game_arr[move.game.idx].cur : move;
	this.game_arr[move.game.idx] = { 'root': move, 'cur': cur };

	// move to start place
	this.userJump( cur );
}


// move to position on board
chess_spider.Board.prototype.userJump = function( move ) {

	//-console.log( 'board.userJump( '+((move)?move.move + move.id:'? ?')+' )' );

	// null move
	if( !move ) move = this.cur_mv;
	//-console.log( 'move=' + move );
	if( !move ) return;
	
	// start
	if( move == 'start' || move == '...' ) move = this.root_mv;

	// prev 5
	else if( move == -5 || move == '\u003c\u003c' ) {
		// otherwise, back off 10 half moves
		for( var i=0, move=this.cur_mv; i<10; i++ ) if( move.pnt ) move = move.pnt;
	}

	// prev 1
	else if( move == -1 || move == '\u003c' ) {
		// otherwise, back off 1 half moves
		for( var i=0, move=this.cur_mv; i<1; i++ ) if( move.pnt ) move = move.pnt;
	}

	// next 1
	else if( move == 1 || move == '\u003e' ) {
		for( var i=0, move=this.cur_mv; i<1; i++ ) if( move.next() ) move = move.next();
	}

	// next 5
	else if( move == 5 || move == '\u003e\u003e' ) {
		for( var i=0, move=this.cur_mv; i<10; i++ ) if( move.next() ) move = move.next();
	}

	// finish
	else if( move == 'finish' || move == '....' ) {
		move = this.cur_mv; 
		while( move.next() ) move = move.next();
	}

	// set board state
	this.cur_mv = move;
	if( move ) this.game_arr[move.game.idx].cur = move;

	// display board
	this.display();

	// these actions require a move
	if( move && move.game && move.game.movelist() ) {

		// clear our hilits - we know ours if same border color
		var hilits = move.game.movelist().getElementsByClassName('cs__hilit');
		for( var i=0; i<hilits.length; i++ )
		if( hilits[i].style.borderColor == this.hilitBorderColor() ) {
			hilits[i].style.backgroundColor = 'inherit';
			hilits[i].className = '';
		}

		// if real move, our highlit
		if( move && move.prv ) {
			move.dom_href().className = 'cs__hilit';
			move.dom_href().style.borderColor = this.hilitBorderColor();
			move.dom_href().style.backgroundColor = this.hilitBackgroundColor();
		}
	}

	// report success
	return true;
}

// get move from board
chess_spider.Board.prototype.get = function( file_row ) {
	var piece = this.square(file_row).firstChild.getAttribute('name').substr(4);
	if( piece.substr(1,1)==' ' )		return ' ';
	else if( piece.substr(0,1)=='b' )	return piece.substr(1,1);
	else					return piece.substr(1,1).toUpperCase();
}

// set move on board
chess_spider.Board.prototype.set = function( file_row, color, piece, must ) {

	var cell = this.square(file_row);

	// piece already sitting there
	if( cell.firstChild && cell.firstChild.name == 'cs__'+color+piece && must!=true ) return;

	// if piece there, rid it
	if( cell.firstChild )  cell.removeChild( cell.firstChild );

	// set piece or strut
	if( piece == ' ' || chess_spider.params.control.disp_piece == 'img' ) {
		var img = new Image();
		img.src = "data:image/gif;base64," + chess_spider.params.piece_imgs[color+piece];
		img.name = 'cs__'+color+piece;
		if( piece!=' ' ) img.addEventListener('dragstart',chess_spider.events.dragstart,false);
		cell.appendChild( img );
	}
	else if( chess_spider.params.control.disp_piece == 'div' ) {
		var div = document.createElement('DIV');
		div.name = 'cs__'+color+piece;
		div.appendChild( document.createTextNode( chess_spider.params.fonts.symbol[color+piece] ) );
		div.addEventListener('dragstart',chess_spider.events.dragstart,false);
		cell.appendChild( div );
	}
	else	throw( 'internal error: unknown control.disp_piece = ' + chess_spider.params.control.disp_piece );
}


// display game after current current move on board, move info at bottom
chess_spider.Board.prototype.display = function() {

	// get pstn
	var pstn = (this.cur_mv && this.cur_mv.pstn) ? this.cur_mv.pstn : chess_spider.params.orig_pstn;

	// display board
	for( var idx = 0, rank = 1; rank <= 8; rank = chess_spider.util.incRank(rank) )
	for( var file = 'a'; file <= 'h'; file = chess_spider.util.incFile(file), idx++ ) {
		this.set( file+rank, ((pstn[idx]>='a') ? 'b' : 'w'), pstn[idx].toLowerCase(), true ); 
	}

	// promotion
	this.dom_promotion('w').style.display = (this.cur_mv && this.cur_mv.promotion && chess_spider.getRank(this.cur_mv.tgt_sq)=='1') ? 'block' : 'none';
	this.dom_promotion('b').style.display = (this.cur_mv && this.cur_mv.promotion && chess_spider.getRank(this.cur_mv.tgt_sq)=='8') ? 'block' : 'none';

	// report move
	this.writeLastMove();

	// which pieces draggable
	this.setDraggable();

	// set finish, nar and comments
	if( this.cur_mv ) {
		this.dom_form().setRadio( 'nar', this.cur_mv.nar );
		this.dom_form().setRadio( 'finish', this.cur_mv.finish );
		this.dom_pre_comment().value = ( this.cur_mv.pre_comment );
		this.dom_comment().value = ( (this.cur_mv.mode=='user') ? this.cur_mv.comment : this.cur_mv.ucomment );
	}

	// enable/disable backspace
	this.dom_panel_backspace().disabled = ( !this.cur_mv || this.cur_mv.mode != 'user' );

	return false;
}

// redisplay last_move in board
chess_spider.Board.prototype.writeLastMove = function() {

	// refresh move on board
	this.dom_last_move().replaceE( ( !this.cur_mv ) 
		? '- -'
		: ((this.cur_mv.move_no) ? this.cur_mv.move_no + ((this.cur_mv.color=='w')?'. ':'... ') : '')
		+ ((this.cur_mv.level>0) ? this.cur_mv.getMove() : '- -')
		+ ((this.cur_mv.nar) ? ' '+chess_spider.regx.nar_arr[this.cur_mv.nar]:'')
		+ ((this.cur_mv.finish) ? ' '+chess_spider.regx.finish_disp_arr[this.cur_mv.finish] : '' ) );

	// refresh move in movelist as well
	if( this.cur_mv && this.cur_mv.dom_href() ) this.cur_mv.dom_href().replaceE( 
		  ((this.cur_mv.level>0) ? this.cur_mv.getMove() : '- -')
		+ ((this.cur_mv.nar) ? chess_spider.regx.nar_arr[this.cur_mv.nar]:'')
		+ ((this.cur_mv.finish) ? ' '+chess_spider.regx.finish_disp_arr[this.cur_mv.finish] : '' ) );
}

// set draggable for pieces on board
// note: chess_spider.interactive controls whether pieces may be moved
chess_spider.Board.prototype.setDraggable = function() {

	// set draggable - will be either img or div
	var pieces = this.dom_table().getElementsByTagName(chess_spider.params.control.disp_piece);
	for( var i=0; i<pieces.length; i++ ) {
		var piece = pieces[i];
		piece.draggable = ( !this.cur_mv || piece.name.substr(4,1) == this.cur_mv.color ) ? false : chess_spider.params.control.interactive;
	}
}


/* ~ show comments - true: show, false: hide, undefined: toggle
chess_spider.Board.prototype.showComments = function( how ) {
*/

// border colors
chess_spider.Board.color_arr =  [
		 {'border':'black', 'background':'lightgray' },
		 {'border':'red', 'background':'tomato' },
		 {'border':'darkgreen', 'background':'chartreuse' },
		 {'border':'blue', 'background':'lavender' },
		 {'border':'deeppink', 'background':'pink' },
		 {'border':'purple', 'background':'thistle' },
		 {'border':'brown', 'background':'wheat' },
		 {'border':'cyan', 'background':'aquamarine' } ];
chess_spider.Board.color_idx = -1;


// getColor - get next available color for a board
chess_spider.Board.nextColorIdx = function() {
	chess_spider.Board.color_idx = (chess_spider.Board.color_idx+1 >= chess_spider.Board.color_arr.length) ? 0 : chess_spider.Board.color_idx+1;
	return chess_spider.Board.color_idx;
}

